﻿using System;
using System.ComponentModel;
using LayeredArchitectureSample.DataTransferObjects;
using LayeredArchitectureSample.Infrastructure;
using LayeredArchitectureSample.Infrastructure.Services;
using LayeredArchitectureSample.ServiceContracts;

namespace LayeredArchitectureSample.ViewModel
{
    internal class NewWareViewModel : INotifyPropertyChanged
    {
        private readonly IServiceOperationInvoker<IRemoteWareRepository> _remoteWareRepository;
        private readonly IExceptionAwareServiceCodeRunner _codeRunner;

        private string _code;
        private WareViewModel _newlyCreatedWare;
        private readonly string _codePropertyName;

        public NewWareViewModel(IServiceOperationInvoker<IRemoteWareRepository> remoteWareRepository,
            IExceptionAwareServiceCodeRunner codeRunner)
        {
            if (remoteWareRepository == null) throw new ArgumentNullException("remoteWareRepository");
            if (codeRunner == null) throw new ArgumentNullException("codeRunner");

            _remoteWareRepository = remoteWareRepository;
            _codeRunner = codeRunner;
            _codePropertyName = Reflection.GetPropertyName(() => this.Code);
        }

        public System.String Code
        {
            get
            {
                return _code;
            }
            set
            {
                _code = value;

                EventRaiser.RaisePropertyChangedEvent(PropertyChanged, this, _codePropertyName);
            }
        }

        public WareViewModel GetNewlyCreatedWare()
        {
            if (_newlyCreatedWare != null)
            {
                return _newlyCreatedWare;
            }

            throw new InvalidOperationException(/*TODO*/);
        }

        public bool CreatedNewWare
        {
            get { return _newlyCreatedWare != null; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 
        /// </summary>
        public void AddToRepository()
        {
            _codeRunner.RunCode(()=>
                                    {
                                        WareDto newWareDto = _remoteWareRepository.Invoke(x => x.AddNewWare(Code));

                                        _newlyCreatedWare = new WareViewModel(newWareDto.Id, newWareDto.Code);
                                    });
        }
    }
}